PHP 8.4.2 Released!

copy

(PHP 4, PHP 5, PHP 7, PHP 8)

copyCopies file

Description

copy(string $from, string $to, ?resource $context = null): bool

Makes a copy of the file from to to.

If you wish to move a file, use the rename() function.

Parameters

from

Path to the source file.

to

The destination path. If to is a URL, the copy operation may fail if the wrapper does not support overwriting of existing files.

Warning

If the destination file already exists, it will be overwritten.

context

A valid context resource created with stream_context_create().

Return Values

Returns true on success or false on failure.

Examples

Example #1 copy() example

<?php
$file
= 'example.txt';
$newfile = 'example.txt.bak';

if (!
copy($file, $newfile)) {
echo
"failed to copy $file...\n";
}
?>

See Also

add a note

User Contributed Notes 13 notes

up
231
simonr_at_orangutan_dot_co_dot_uk
20 years ago
Having spent hours tacking down a copy() error: Permission denied , (and duly worrying about chmod on winXP) , its worth pointing out that the 'destination' needs to contain the actual file name ! --- NOT just the path to the folder you wish to copy into.......
DOH !
hope this saves somebody hours of fruitless debugging
up
128
cooper at asu dot ntu-kpi dot kiev dot ua
18 years ago
It take me a long time to find out what the problem is when i've got an error on copy(). It DOESN'T create any directories. It only copies to existing path. So create directories before. Hope i'll help,
up
60
steve a h
16 years ago
Don't forget; you can use copy on remote files, rather than doing messy fopen stuff. e.g.

<?php
if(!@copy('http://someserver.com/somefile.zip','./somefile.zip'))
{
$errors= error_get_last();
echo
"COPY ERROR: ".$errors['type'];
echo
"<br />\n".$errors['message'];
} else {
echo
"File copied from remote!";
}
?>
up
28
promaty at gmail dot com
13 years ago
Here is a simple script that I use for removing and copying non-empty directories. Very useful when you are not sure what is the type of a file.

I am using these for managing folders and zip archives for my website plugins.

<?php

// removes files and non-empty directories
function rrmdir($dir) {
if (
is_dir($dir)) {
$files = scandir($dir);
foreach (
$files as $file)
if (
$file != "." && $file != "..") rrmdir("$dir/$file");
rmdir($dir);
}
else if (
file_exists($dir)) unlink($dir);
}

// copies files and non-empty directories
function rcopy($src, $dst) {
if (
file_exists($dst)) rrmdir($dst);
if (
is_dir($src)) {
mkdir($dst);
$files = scandir($src);
foreach (
$files as $file)
if (
$file != "." && $file != "..") rcopy("$src/$file", "$dst/$file");
}
else if (
file_exists($src)) copy($src, $dst);
}
?>

Cheers!
up
29
absorbentshoulderman at gmail dot com
11 years ago
A nice simple trick if you need to make sure the folder exists first:

<?php

$srcfile
='C:\File\Whatever\Path\Joe.txt';
$dstfile='G:\Shared\Reports\Joe.txt';
mkdir(dirname($dstfile), 0777, true);
copy($srcfile, $dstfile);

?>

That simple.
up
5
someone at terrasim dot com
3 years ago
On Windows, php-7.4.19-Win32-vc15-x64 - copy() corrupted a 6GB zip file. Our only recourse was to write:

function file_win_copy( $src, $dst ) {
shell_exec( 'COPY "'.$src.'" "'.$dst.'"');
return file_exists($dest);
}
up
10
tom at r dot je
16 years ago
It's worth noting that copy() sets the destination file's last modified time/date.
up
10
ASchmidt at Anamera dot net
10 years ago
Below a code snippet for downloading a file from a web server to a local file.

It demonstrates useful customizations of the request (such as setting a User-Agent and Referrer, often required by web sites), and how to download only files if the copy on the web site is newer than the local copy.

It further demonstrates the processing of response headers (if set by server) to determine the timestamp and file name. The file type is checked because some servers return a 200 OK return code with a textual "not found" page, instead of a proper 404 return code.

<?php
// $fURI: URL to a file located on a web server
// $target_file: Path to a local file

if ( file_exists( $target_file ) ) {
$ifmodhdr = 'If-Modified-Since: '.date( "r", filemtime( $target_file ) )."\r\n";
}
else {
$ifmodhdr = '';
}

// set request header for GET with referrer for modified files, that follows redirects
$arrRequestHeaders = array(
'http'=>array(
'method' =>'GET',
'protocol_version' =>1.1,
'follow_location' =>1,
'header'=> "User-Agent: Anamera-Feed/1.0\r\n" .
"Referer: $source\r\n" .
$ifmodhdr
)
);
$rc = copy( $fURI, $target_file, stream_context_create($arrRequestHeaders) );

// HTTP request completed, preserve system error, if any
if( $rc ) {
if (
fclose( $rc ) ) {
unset(
$err );
}
else {
$err = error_get_last();
}
}
else {
$err = error_get_last();
}

// Parse HTTP Response Headers for HTTP Status, as well filename, type, date information
// Need to start from rear, to get last set of headers after possible sets of redirection headers
if ( $http_response_header ) {
for (
$i = sizeof($http_response_header) - 1; $i >= 0; $i-- ) {
if (
preg_match('@^http/\S+ (\S{3,}) (.+)$@i', $http_response_header[$i], $http_status) > 0 ) {
// HTTP Status header means we have reached beginning of response headers for last request
break;
}
elseif (
preg_match('@^(\S+):\s*(.+)\s*$@', $http_response_header[$i], $arrHeader) > 0 ) {
switch (
$arrHeader[1] ) {
case
'Last-Modified':
if ( !isset(
$http_content_modtime) ) {
$http_content_modtime = strtotime( $arrHeader[2] );
}
break;
case
'Content-Type':
if ( !isset(
$http_content_image_type) ) {
if (
preg_match('@^image/(\w+)@ims', $arrHeader[2], $arrTokens) > 0 ) {
if (
in_array(strtolower($arrTokens[1]), $arrValidTypes)) {
$http_content_image_type = $arrTokens[1];
break;
}
}
throw new
Exception( "Error accessing file $fURI; invalid content type: $arrHeader[2]", 2);
}
break;
case
'Content-Disposition':
if ( !isset(
$http_content_filename) && preg_match('@filename\\s*=\\s*(?|"([^"]+)"|([\\S]+));?@ims', $arrHeader[2], $arrTokens) > 0 ) {
$http_content_filename = basename($arrTokens[1]);
}
break;
}
}
}
}

if (
$http_status ) {
// Make sure we have good HTTP Status
switch ( $http_status[1] ) {
case
'200':
// SUCCESS: HTTP Status is "200 OK"
break;
case
'304':
throw new
Exception( "Remote file not newer: $fURI", $http_status[1] );
break;
case
'404':
throw new
Exception( "Remote file not found: $fURI", $http_status[1] );
break;
default:
throw new
Exception( "HTTP Error, $http_status[2], accessing $fURI", $http_status[1] );
break;
}
}
elseif (
$err ) {
// Protocol / Communication error
throw new Exception( $err['message']/*."; Remote file: $fURI"*/, $err['type'] );
}
else {
// No HTTP status and no error
throw new customException( "Unknown HTTP response accessing $fURI: $http_response_header[0]", -1 );
}
?>

Notes:
1. Currently copy() does NOT appropriately handle the 304 response code. Instead of NOT performing a copy (possibly setting the RC), it will overwrite the target file with an zero length file.
2. There may be a problem accessing a list of remote files when HTTP 1.1 protocol is used. If you experience time-out errors, try the default 1.0 protocol version.
up
5
hugo_2000 at gmx dot at
9 years ago
If you try to copy a file to itself - e.g. if the target directory is just a symlink to the source directory - copy will return false. just like on the command line.
up
4
Vinicio Coletti
8 years ago
Copying large files under Windows 8.1, from one NTFS filesystem to another NTFS filesystem, results in only the first 4 GiB copied and the rest of the file is ignored.

So, if you think to have files larger than 4 GiB, instead of doing:
copy($source,$destination);
it is much better to do something like:
exec("xcopy $source $destination");

I will check to see if this issue is valid also under Linux.
It depends on PHP not being compiled in 64 bit mode?
up
19
gimmicklessgpt at gmail dot com
15 years ago
Here's a simple recursive function to copy entire directories

Note to do your own check to make sure the directory exists that you first call it on.

<?php
function recurse_copy($src,$dst) {
$dir = opendir($src);
@
mkdir($dst);
while(
false !== ( $file = readdir($dir)) ) {
if ((
$file != '.' ) && ( $file != '..' )) {
if (
is_dir($src . '/' . $file) ) {
recurse_copy($src . '/' . $file,$dst . '/' . $file);
}
else {
copy($src . '/' . $file,$dst . '/' . $file);
}
}
}
closedir($dir);
}
?>
up
8
eng-ayman at aymax dot net
15 years ago
some hosts disable copy() function and say its for security

and for some copy is important so this is and simple function that do same as copy function effect

how smart php can help us l like php

<?php
function copyemz($file1,$file2){
$contentx =@file_get_contents($file1);
$openedfile = fopen($file2, "w");
fwrite($openedfile, $contentx);
fclose($openedfile);
if (
$contentx === FALSE) {
$status=false;
}else
$status=true;

return
$status;
}
?>
up
0
greg at hartwig dot com
1 month ago
To copy a file and preserve the file timestamps:

<?php
if (copy($from, $to))
touch($to, filemtime($from), fileatime($from));
?>
To Top